// Bristleback plugin - Copyright (c) 2010 bristleback.googlecode.com
// ---------------------------------------------------------------------------
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
// This library is distributed in the hope that it will be useful,
// but without any warranty; without even the implied warranty of merchantability
// or fitness for a particular purpose.
// You should have received a copy of the GNU Lesser General Public License along
// with this program; if not, see <http://www.gnu.org/licenses/lgpl.html>.
// ---------------------------------------------------------------------------
package pl.bristleback.server.bristle.messages;

import org.apache.log4j.Logger;
import org.jwebsocket.api.WebSocketServer;
import pl.bristleback.server.bristle.config.BristleConfiguration;
import pl.bristleback.server.bristle.config.MessageContainerResolver;

/**
 * Message controller communicates with Bristle plugin and performs operations on message dispatcher and message senders.
 * It provides method to load {@link pl.bristleback.server.bristle.messages.MessageContainer} object,
 * assign senders and dispatcher with server, and finally, export senders and start dispatching messages.
 * <p/>
 * Created on: 2010-09-25 10:14:37 <br/>
 *
 * @author Wojciech Niemiec
 */
public final class MessageController {
  private static Logger log = Logger.getLogger(MessageController.class.getName());

  private MessageContainer messageContainer;

  /**
   * Loads message container using plugin settings. It chooses {@link pl.bristleback.server.bristle.config.MessageContainerResolver}
   * implementation, based on plugin settings. From then, resolver object is used to load message container, which is then stored
   * in controller. It sets dispatcher in all loaded senders by invoking
   * {@link pl.bristleback.server.bristle.config.MessageContainerResolver#assignDispatcherToSenders(MessageContainer)} method.
   *
   * @param configuration Bristleback plugin configuration.
   */
  public void loadMessageContainer(BristleConfiguration configuration) {
    MessageContainerResolver messageContainerResolver = configuration.getMessageContainerResolver();
    loadContainerByResolver(messageContainerResolver, configuration);
  }

  private void loadContainerByResolver(MessageContainerResolver messageContainerResolver, BristleConfiguration configuration) {
    messageContainer = messageContainerResolver.createMessageContainer(configuration);
    messageContainerResolver.assignDispatcherToSenders(messageContainer);
  }

  /**
   * Assigns server into message dispatcher and message senders.
   *
   * @param server jwebsocket server implementation.
   */
  public void assignServer(WebSocketServer server) {
    messageContainer.getMessageDispatcher().setServer(server);
    for (MessageSender sender : messageContainer.getSenders().values()) {
      sender.setServer(server);
    }
  }

  /**
   * Exports senders, after invoking this method, senders can be obtained from {@link pl.bristleback.server.bristle.messages.MessageSendersExporter} class.
   */
  public void exportSenders() {
    MessageSendersExporter.setMessageSenders(messageContainer.getSenders());
  }

  /**
   * Starts dispatcher, invoking its startDispatching() method.
   */
  public void startDispatcher() {
    if (messageContainer == null || messageContainer.getMessageDispatcher() == null) {
      throw new IllegalStateException("Dispatcher is not set");
    }
    messageContainer.getMessageDispatcher().startDispatching();
  }

  /**
   * Stops dispatching, invoking its stopDispatching() method.
   */
  public void stopDispatcher() {
    if (messageContainer == null || messageContainer.getMessageDispatcher() == null) {
      throw new IllegalStateException("Dispatcher is not set");
    }
    messageContainer.getMessageDispatcher().stopDispatching();
  }

  /**
   * Gets loaded message container. Returns null if container is not loaded yet.
   *
   * @return message container.
   */
  public MessageContainer getMessageContainer() {
    return messageContainer;
  }
}
